package me.work.pay.jsyl.app.utils;

import android.content.Context;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.net.wifi.ScanResult;
import android.net.wifi.WifiConfiguration;
import android.net.wifi.WifiInfo;
import android.net.wifi.WifiManager;
import android.text.TextUtils;

import com.chaomeng.a8sdklibrary.utils.LogUtil;

import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

import static android.content.Context.WIFI_SERVICE;

/**
 * @author SQSong
 * @date 2017/10/3
 */
public class WifiToolUtil {

    private static final String TAG = "WifiToolUtil";

    public static String getWifiEncryption(String capabilities) {
        String encrypt;
        switch (getWifiState(capabilities)) {
            case 1:
                encrypt = "WPA/WPA2";
                break;
            case 2:
                encrypt = "WPA2";
                break;
            case 3:
                encrypt = "WPA";
                break;
            case 4:
                encrypt = "WEP";
                break;
            default:
                encrypt = "开放";
                break;
        }
        return encrypt;
    }

    public static boolean isWifiEnable(Context context) {
        WifiManager wifiManager = (WifiManager) context.getApplicationContext().getSystemService(WIFI_SERVICE);
        return wifiManager.isWifiEnabled();
    }

    public static int getWifiState(Context context, ScanResult result) {
        int type;
        if (isWifiConnected(context, result)) {
            type = 0;
        } else {
            type = getWifiState(result.capabilities);
        }
        return type;
    }

    private static int getWifiState(String capabilities) {
        int type;
        if (capabilities.contains("WPA-PSK") && capabilities.contains("WPA2-PSK")) {
            type = 1;
        } else if (capabilities.contains("WPA2-PSK")) {
            type = 2;
        } else if (capabilities.contains("WPA-PSK")) {
            type = 3;
        } else if (capabilities.contains("WEP")) {
            type = 4;
        } else { // open
            type = 5;
        }
        return type;
    }

    public static String changeWifiDescription(Context context, ScanResult scanResult) {
        String desc = null;
        if (scanResult == null) {
            return desc;
        }
        WifiManager wifiManager = (WifiManager) context.getApplicationContext().getSystemService(WIFI_SERVICE);
        ConnectivityManager mConnectivityManage = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        WifiInfo connectionInfo = wifiManager.getConnectionInfo();
        String infoBssid = WifiToolUtil.removeDoubleQuotes(connectionInfo.getBSSID());
        String scanBssid = scanResult.BSSID;
        NetworkInfo.DetailedState state = mConnectivityManage.getNetworkInfo(ConnectivityManager.TYPE_WIFI).getDetailedState();
        if (state == NetworkInfo.DetailedState.CONNECTED) {
            if (infoBssid.endsWith(scanBssid)) {
                desc = "已连接";
            }
        } else if (state == NetworkInfo.DetailedState.CONNECTING || state == NetworkInfo.DetailedState.OBTAINING_IPADDR) {
            if (infoBssid.endsWith(scanBssid)) {
                desc = "连接中...";
            }
        } else if (state == NetworkInfo.DetailedState.FAILED) {
            if (infoBssid.endsWith(scanBssid)) {
                desc = "连接失败";
            }
        } else {
            if (infoBssid.endsWith(scanBssid)) {
                desc = "身份验证中...";
            }
        }
        return desc;
    }

    public static boolean isWifiConfigured(Context context, ScanResult result) {
        if (context == null || result == null) {return false;}
        WifiManager wifiManager = (WifiManager) context.getApplicationContext().getSystemService(WIFI_SERVICE);
        List<WifiConfiguration> networks = wifiManager.getConfiguredNetworks();
        if (networks == null || networks.isEmpty()) {return false;}
        for (WifiConfiguration configuration : networks) {
            if (result.SSID != null && result.SSID.equals(removeDoubleQuotes(configuration.SSID))) {
                return true;
            }
        }
        return false;
    }

    public static WifiConfiguration getWifiConfiguration(Context context, ScanResult result) {
        if (context == null || result == null) {return null;}
        WifiManager wifiManager = (WifiManager) context.getSystemService(WIFI_SERVICE);
        List<WifiConfiguration> networks = wifiManager.getConfiguredNetworks();
        if (networks == null || networks.isEmpty()) {return null;}
        for (WifiConfiguration configuration : networks) {
            if (result.SSID != null && result.SSID.equals(removeDoubleQuotes(configuration.SSID))) {
                return configuration;
            }
        }
        return null;
    }

    private static boolean isWifiConnected(Context context, ScanResult result) {
        WifiManager wifiManager = (WifiManager) context.getApplicationContext().getSystemService(WIFI_SERVICE);
        WifiInfo connectionInfo = wifiManager.getConnectionInfo();
        if (result.SSID.equals(removeDoubleQuotes(connectionInfo.getSSID()))
                && result.BSSID.equals(connectionInfo.getBSSID())) {
            return true;
        }
        return false;
    }

    public static boolean isWifiConnect(Context context) {
        ConnectivityManager connManager = (ConnectivityManager) context.getSystemService(Context.CONNECTIVITY_SERVICE);
        NetworkInfo wifiInfo = connManager.getNetworkInfo(ConnectivityManager.TYPE_WIFI);
        return wifiInfo != null && wifiInfo.isConnected();
    }

    public static WifiConfiguration buildWifiConfiguration(String BSSID, String SSID, String password, int wifiState) {
        WifiConfiguration config = new WifiConfiguration();
        config.SSID = "\"" + SSID + "\"";
        config.BSSID = BSSID;
        if (wifiState == 0) {
            //SECURITY_NONE
            config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
        } else if (wifiState == 1 || wifiState == 2 || wifiState == 3) {
            // for WPA.
            config.preSharedKey = "\"" + password + "\"";
            config.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);
            config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
            config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
            config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.WPA_PSK);
            config.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);
            config.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
            config.allowedProtocols.set(WifiConfiguration.Protocol.RSN);
            config.allowedProtocols.set(WifiConfiguration.Protocol.WPA);
            config.status = WifiConfiguration.Status.ENABLED;
        } else if (wifiState == 4) {
            // for WEP;
            if (!TextUtils.isEmpty(password)) {
                if (isHexWepKey(password)) {
                    config.wepKeys[0] = password;
                } else {
                    config.wepKeys[0] = "\"" + password + "\"";
                }
            }
            config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
            config.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.OPEN);
            config.allowedAuthAlgorithms.set(WifiConfiguration.AuthAlgorithm.SHARED);
            config.wepTxKeyIndex = 0;
        } else {
            // for open.
            config.allowedKeyManagement.set(WifiConfiguration.KeyMgmt.NONE);
            config.allowedProtocols.set(WifiConfiguration.Protocol.RSN);
            config.allowedAuthAlgorithms.clear();
            config.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.CCMP);
            config.allowedPairwiseCiphers.set(WifiConfiguration.PairwiseCipher.TKIP);
            config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP40);
            config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.WEP104);
            config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.CCMP);
            config.allowedGroupCiphers.set(WifiConfiguration.GroupCipher.TKIP);
        }
        return config;
    }

    private static boolean isHexWepKey(String wepKey) {
        final int len = wepKey.length();

        // WEP-40, WEP-104, and some vendors using 256-bit WEP (WEP-232?)
        if (len != 10 && len != 26 && len != 58) {
            return false;
        }

        return isHex(wepKey);
    }

    private static boolean isHex(String key) {
        for (int i = key.length() - 1; i >= 0; i--) {
            final char c = key.charAt(i);
            if (!(c >= '0' && c <= '9' || c >= 'A' && c <= 'F' || c >= 'a' && c <= 'f')) {
                return false;
            }
        }

        return true;
    }

    public static String getWifiLevelString(int level) {
        String desc;
        int signalLevel = WifiManager.calculateSignalLevel(level, 4);
        switch (signalLevel) {
            case 3:
                desc = "极强";
                break;
            case 2:
                desc = "较强";
                break;
            case 1:
                desc = "强";
                break;
            default:
                desc = "弱";
                break;
        }
        return desc;
    }

    private static String removeDoubleQuotes(String string) {
        if (TextUtils.isEmpty(string)) {
            return "";
        }
        int length = string.length();
        if ((length > 1) && (string.charAt(0) == '"')
                && (string.charAt(length - 1) == '"')) {
            return string.substring(1, length - 1);
        }
        return string;
    }

    public static String getSSID(String string) {
        if (TextUtils.isEmpty(string)) {
            return "";
        }
        return string.substring(1, string.length() - 1);
    }

    /**
     * 反射获取connect方法
     */
    public static boolean connect(WifiManager manager, WifiConfiguration wifiConfiguration) {
        try {
            Class ActionListener = Class.forName("android.net.wifi.WifiManager$ActionListener", false, null);
            Method connectWifiConfig = WifiManager.class.getDeclaredMethod("connect", WifiConfiguration.class, ActionListener);
            if (connectWifiConfig == null) {
                return false;
            }
            connectWifiConfig.invoke(manager, wifiConfiguration, null);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
        }
        return false;
    }

    private static WifiManager mWifiManager;
    private static List<ScanResult> mScanResults = new ArrayList<>();

    public static void doConnectWifi(String bssid, String ssid, String pswd, Context mContext) {
        mWifiManager = (WifiManager) mContext.getApplicationContext().getSystemService(WIFI_SERVICE);
        mWifiManager.startScan();
        mScanResults = mWifiManager.getScanResults();
//        if (view != null) {
//            view.setText("正在配网中...");
//        }
        LogUtil.i(TAG, "bssid : " + bssid);
        //如果bssid为空，在扫描到的wifi信息中做比对
        if (bssid != null && TextUtils.isEmpty(bssid)) {
            LogUtil.i(TAG, "mScanResults.size() : " + mScanResults.size());
            if (mScanResults.size() > 0) {
                for (int i = 0; i < mScanResults.size(); i++) {
                    LogUtil.i(TAG, "ssid : " + ssid + "   mScanResults ssid : " + mScanResults.get(i).SSID);
                    if (ssid.equals(mScanResults.get(i).SSID)) {
                        bssid = mScanResults.get(i).BSSID;
                    }
                }
            }
        }

        LogUtil.i(TAG, "scanresult end bssid : " + bssid);
//        if (bssid.isEmpty()) {
//            return;
//        }

        //过滤出我们真正的名字
        ScanResult rscanResult = null;
        ScanResult rscanResult2 = null;
        for (int i = 0; i < mScanResults.size(); i++) {
            ScanResult scanResult = mScanResults.get(i);
            if (scanResult.BSSID.equalsIgnoreCase(bssid)) {
                rscanResult = scanResult;
                break;
            }
            if (scanResult.BSSID.substring(0, scanResult.BSSID.length() - 2).equalsIgnoreCase(bssid.substring(0, scanResult.BSSID.length() - 2))) {
                rscanResult2 = scanResult;
            }
        }

        int defaultWifiState = 1;
        if (rscanResult != null) {
            bssid = rscanResult.BSSID;
            //隐藏网络，扫描不到ssid，就使用传进来的
            if (!rscanResult.SSID.isEmpty()) {
                ssid = rscanResult.SSID;
            }
            defaultWifiState = WifiToolUtil.getWifiState(rscanResult.capabilities);
            LogUtil.i(TAG, "bssid : " + bssid + "  ssid : " + ssid + "   defaultWifiState : " + defaultWifiState);
        }

        if (rscanResult == null && rscanResult2 != null) {
            bssid = rscanResult2.BSSID;
            //隐藏网络，扫描不到ssid，就使用传进来的
            if (!rscanResult2.SSID.isEmpty()) {
                ssid = rscanResult2.SSID;
            }
            defaultWifiState = WifiToolUtil.getWifiState(rscanResult2.capabilities);
            LogUtil.i(TAG, "bssid : " + bssid + "  ssid : " + ssid + "   defaultWifiState : " + defaultWifiState);
        }
        WifiConfiguration wifiConfiguration = WifiToolUtil.buildWifiConfiguration(bssid.toLowerCase(), ssid, pswd, defaultWifiState);
        int netId = mWifiManager.addNetwork(wifiConfiguration);
        LogUtil.i(TAG, "netId : " + netId);
        //获取反射，用来保存传入的wifi信息
        WifiToolUtil.connect(mWifiManager, wifiConfiguration);
    }
    public static void conn(String bssid,String ssid,String pswd){
        int defaultWifiState = 1;
        WifiConfiguration wifiConfiguration = WifiToolUtil.buildWifiConfiguration(bssid.toLowerCase(), ssid, pswd, defaultWifiState);
        int netId = mWifiManager.addNetwork(wifiConfiguration);
        LogUtil.i(TAG, "netId : " + netId);
        //获取反射，用来保存传入的wifi信息
        WifiToolUtil.connect(mWifiManager, wifiConfiguration);
    }

    public static void removeWifi_2(Context context) {
        try {
            Class<?> actionListener = null;
            try {
                actionListener = Class.forName("android.net.wifi.WifiManager$ActionListener");
            } catch (ClassNotFoundException e) {
                e.printStackTrace();
            }
            Method method = null;
            try {
                method = WifiManager.class.getDeclaredMethod("forget", int.class, actionListener);
            } catch (NoSuchMethodException e) {
                e.printStackTrace();
            }
            if (mWifiManager == null) {
                mWifiManager = (WifiManager) context.getApplicationContext().getSystemService(WIFI_SERVICE);
            }
            List<WifiConfiguration> wifiConfigs = mWifiManager.getConfiguredNetworks();
            //忘记所有wifi密码
            for (WifiConfiguration wifiConfig : wifiConfigs) {
                LogUtil.e(TAG, "forget SSID = " + wifiConfig.SSID + " netId = " + String.valueOf(wifiConfig.networkId));
                method.invoke(mWifiManager, wifiConfig.networkId, null);
            }
        } catch (IllegalAccessException | InvocationTargetException e) {
            e.printStackTrace();
        }
    }

    public static void getWifiConfig(Context context) {
        WifiManager wifiManager = (WifiManager) context.getApplicationContext().getSystemService(Context.WIFI_SERVICE);
        List<WifiConfiguration> configs = wifiManager.getConfiguredNetworks();
        if (configs == null || configs.size() <= 0) {
            return;
        }
        for (WifiConfiguration config : configs) {
        }
    }
}
